package org.xiaohaoniu.controller;

import jakarta.servlet.http.HttpServletResponse;
import org.bytedeco.javacv.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.OutputStream;

@RestController
public class MjpegStreamController {

    @GetMapping("/video.mjpeg")
    public void streamMJPEG(HttpServletResponse response) {
        response.setContentType("multipart/x-mixed-replace; boundary=--frame");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Connection", "close");
        FFmpegLogCallback.set();

        // windows
//        String filename = "video=USB Video Device";
//        String format = "dshow";

        //linux
        String filename = "/dev/video0";
        String format = "video4linux2";

        try (OutputStream out = response.getOutputStream();
             FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filename)) {
            grabber.setFormat(format);
            grabber.setImageWidth(640);
            grabber.setImageHeight(480);
            grabber.setFrameRate(20);
            grabber.setOption("video_size", "640x480"); // 尝试显式指定
            grabber.setOption("framerate", "30");
            grabber.setOption("pixel_format", "mjpeg"); // 关键点：强制使用 MJPEG

            grabber.setImageWidth(640);  // 从1080P降到720P/480P
            grabber.setImageHeight(480);
            grabber.setFrameRate(15);    // 从30FPS降到15-20FPS

            //优化
            grabber.setOption("fflags", "nobuffer");
            grabber.setOption("flags", "low_delay");
            grabber.setOption("rtbufsize", "10M");
            grabber.setOption("threads", "1");

            grabber.start();

            Java2DFrameConverter converter = new Java2DFrameConverter();

            while (true) {
                Frame frame = grabber.grabImage(); // 只抓图像帧
                if (frame == null) continue;

                BufferedImage bufferedImage = converter.convert(frame);
                if (bufferedImage == null) continue;

                // 转为 JPEG 并写入 HTTP 流
                out.write(("--frame\r\n" +
                        "Content-Type: image/jpeg\r\n\r\n").getBytes());

                ImageIO.write(bufferedImage, "jpg", out);
                out.write("\r\n".getBytes());

                out.flush();

                // 控制帧率
                Thread.sleep(50); // 约 20fps
            }

        } catch (Exception e) {
            System.out.println("MJPEG 流中断：" + e.getMessage());
        }
    }
}
